home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / dev / debug / apurify_v1_1.lha / apurify / lib / APfuncs.c next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  22.3 KB  |  1,028 lines

  1. /*
  2.  *    APfuncs.c
  3.  */
  4.  
  5. /*    GUEULANTE... (qui date un peu, et qui est bourree de mauvaise
  6.  *    foi :-) PASSEZ CE COMMENTAIRE !
  7.  *
  8.  *  Pourquoi 1 seul fichier de fonctions ? Bonne question ! La logique de
  9.  *  programmation habituelle impose de programmer structure. Cela implique 
  10.  *  l'utilisation de modules separes pour chaque fonction de base.
  11.  *
  12.  *  On dit que cela permet d'avoir un code plus lisible (pourquoi pas ?).
  13.  *  Cependant, il existe un probleme dans le cadre d'une librairie de
  14.  *  fonctions. En effet certaines fonctions peuvent etre vue privee dans
  15.  *  un module (static en C). D'autres privee a la librairie. C'est a dire
  16.  *  une fonction non disponible a l'exterieur de la librairie, mais publique
  17.  *  pour chaque module de la librairie (la fonction do_print() en est un
  18.  *  exemple). Malheureusement en C il est impossible de faire un tel
  19.  *  distinguo, puisqu'il ne connait que la privaute au sein d'un module.
  20.  *
  21.  *  En C on est donc contraint a declarer ces fonctions publique. Cela pose
  22.  *  des pbs a l'utilisateur de la librairie qui peut utiliser cette fonction
  23.  *  sans connaitre son existance et provoquer des bugs (re-definition d'une
  24.  *  fonction de bibliotheque). Par exemple, la fonction t_format()
  25.  *  (_pfmtone() pour DICE) est parfois utilisee par printf() pour la sortie
  26.  *  et je vous deconseille alors d'avoir une fonction qui porte le meme nom
  27.  *  dans votre programme. La solution alors utilisee est de choisir le nom
  28.  *  des fonctions de telle sorte qu'il soit peu probable que l'utilisateur
  29.  *  choisisse un homonyme. Cepandant puisque ces fonctions ne sont pas
  30.  *  doccumentees, il n'est pas impossible que cela arrive. De plus, les
  31.  *  noms sont alors parfois prefixes d'une sequence identique (_ ou lib_
  32.  *  en general). Ainsi le code apparait beaucoup moins clair a lire:
  33.  *
  34.  *        int _lib_purify_do_print(fmt, ... )...
  35.  *        void proc_x()
  36.  *        {
  37.  *        _lib_purify_do_print("Ah que le nom de cette procedure"
  38.  *                 "est peinible a ecrire !!!!");
  39.  *        }
  40.  *
  41.  *  La solution que je choisis pour ce source c'est de tout garder dans
  42.  *  Un seul fichier et tout les static du modules sont donc les static de
  43.  *  la bibliotheque. Ca fait un peu bordelique (le code depasse 19Ko),
  44.  *  mais bon, s'il le faut, je decouperai cela un peu peut-etre (mais cela
  45.  *  ferait passer beaucoup de procedures de static a public pour presque
  46.  *  rien, donc je verrais... :-). En attendant, le code est comme ca. Ce que
  47.  *  je lui reproche le plus est qu'il pourrait etre re-organise (mais bon,
  48.  *  je travaille sur diskette avec 1Mo et j'ai pas specialement envie de
  49.  *  passer mes nuits dessus). En general, les gens qui sont tres "modules"
  50.  *  passent bcp de temps a decouper leur code alors qu'il est deja assez
  51.  *  petit. Cela fait apparaitre plein de bugs nouveaux qu'il mettent un temps
  52.  *  fou a trouver. En gros je pense que cela fait perdre bcp de temps pour
  53.  *  pas grand chose tout compte fait (c'est un peu le meme phenomene avec
  54.  *  les programmateurs "objets" qui font rammer leurs programmes a cause
  55.  *  d'un nombre d'acces a des fonctions(methodes) bcp trop grand !).
  56.  *
  57.  */
  58.  
  59. #include <stdio.h>
  60.  
  61. #ifdef    FRANCAIS
  62. #define TRD(FRANCAIS, ANGLAIS)  FRANCAIS    /* which translation ? */
  63. #else
  64. #define TRD(FRANCAIS, ANGLAIS)  ANGLAIS
  65. #endif
  66.  
  67. #define ifn(x)        if(!(x))        /* usefull define */
  68.  
  69. #define WARNING     "**** APURIFY WARNING !"
  70. #define ERROR        "**** APURIFY ERROR !"
  71.  
  72. #define LVOAllocMem    (-0xC6)
  73. #define LVOFreeMem    (-0xD2)
  74.  
  75. #define LARG_LINE    76
  76. #define MARG_LINE    8
  77.  
  78. #define CACHE_SIZE    8 /* nb chunks en cache */
  79.  
  80. extern void    *AsmAllocMem(),AsmFreeMem();
  81. extern void    *StdAlloc(),StdFree();
  82.  
  83. #define APopen        1
  84. #define APlock        2
  85. #define APwarn        4
  86. #define    APreport    8
  87.  
  88. typedef unsigned long ULONG;
  89. typedef unsigned char UBYTE;
  90.  
  91. typedef struct simplecli
  92.     {
  93.     char tab1[60];
  94.     ULONG Module;
  95.     } simplecli;
  96.  
  97. typedef struct simpletask
  98.     {
  99.     char tab[58];
  100.     ULONG BasPileTache,HautPileTache;
  101.     char tab2[62];
  102.     ULONG SegList;
  103.     char tab3[40];
  104.     ULONG CLI;
  105.     } simpletask;
  106.  
  107. static ULONG APflg=0;
  108. static simpletask *ThisTask;
  109. extern simpletask *FindTask();
  110. extern ULONG SetFunction();
  111. static ULONG MallocProc,FreeProc;
  112.  
  113. char *AP_procname=TRD("Aucune procedure !",
  114.               "No procedure !");
  115.  
  116. typedef struct pile
  117.     {
  118.     struct pile *next;
  119.     char *name;
  120.     } pile;
  121.  
  122. static pile *stack=NULL;
  123. static int cnt=0;
  124.  
  125. extern void *malloc();
  126.  
  127. typedef struct mchunk
  128.     {
  129.     struct mchunk *prev,*next;
  130.     ULONG deb,fin;            /* bornes incluses */
  131.     char *name;
  132.     UBYTE attr;
  133.     } mchunk;
  134.  
  135. #define attr_rd  1
  136. #define attr_wr  2
  137. #define attr_sys 4
  138.  
  139. static mchunk *mfirst=NULL;
  140.  
  141. static char *line;
  142.  
  143. static char *blocks(c)
  144.     mchunk *c;
  145.     {
  146.     static char buf[80];
  147.     sprintf(buf,"[0x%08x(%d) %c%c%c (%s)]",
  148.         c->deb, c->fin-c->deb+1,
  149.         c->attr & attr_rd  ? 'R':'-',
  150.         c->attr & attr_wr  ? 'W':'-',
  151.         c->attr & attr_sys ? 'S':'-',
  152.         c->name);
  153.     return buf;
  154.     }
  155.  
  156. static void do_spc(i)
  157.     int i;
  158.     {
  159.     while(i--) fputc(' ',stderr);
  160.     }
  161.  
  162. static int isspc(c)
  163.     char c;
  164.     {
  165.     return (c>0) && (c<=' ');
  166.     }
  167.  
  168. static void do_print(fmt, ...)
  169.     char *fmt;
  170.     {
  171.     ULONG *b = (&fmt) + 1;
  172.     char *s,*buff;
  173.     ifn(buff = malloc(1024)) /* 1024 suffisant ? */
  174.         {
  175.         fprintf(stderr,TRD(
  176.             WARNING" Impossible allouer memoire pour \"",
  177.             WARNING" Can't alloc memory for \""));
  178.         fprintf(stderr, fmt, b[0],b[1],b[2],b[3],b[4],b[5]);
  179.         fprintf(stderr,"\"\n");
  180.         return;
  181.         }
  182.     sprintf(buff, fmt, b[0],b[1],b[2],b[3],b[4],b[5]);
  183.     if(line)
  184.         {
  185.         if(s = malloc(1+strlen(line)+strlen(buff)))
  186.             {
  187.             strcpy(s, line);strcat(s,buff);
  188.             free(line);line = s;
  189.             }
  190.         else    fprintf(stderr,TRD(
  191.                        WARNING" Impossible allouer memoire"
  192.                        " pour \"%s\"\n",
  193.  
  194.                        WARNING" Can't alloc memory for \"%s"
  195.                        "\"\n"),
  196.                 buff);
  197.         }
  198.     else
  199.         {
  200.         if(s = malloc(1+strlen(buff)))
  201.             {
  202.             strcpy(s, buff);line = s;
  203.             }
  204.         else    fprintf(stderr,TRD(
  205.                        WARNING" Impossible allouer memoire"
  206.                        " pour \"%s\"\n",
  207.  
  208.                        WARNING" Can't alloc memory for \"%s"
  209.                        "\"\n"),
  210.                 buff);
  211.         }
  212.     free(buff);
  213.     }
  214.  
  215. static void do_dump(mg,md)
  216.     int mg,md;
  217.     {
  218.     int i,nbmot,nbcar;
  219.     char *s=line,*debut_ligne,*fin_ligne;
  220.  
  221.     ifn(APflg & APreport) goto end;
  222.  
  223.     md -= mg;
  224.  
  225.     while(*s)
  226.         {
  227.         /* recuperation stats pour ligne: nbmots, nbcar .. */
  228.         debut_ligne = s;
  229.         nbmot = nbcar = 0;
  230.         while(1)
  231.             {
  232.             int lenmot;
  233.             while(isspc(*s)) ++s;
  234.             fin_ligne = s;
  235.             if(!*s) break;
  236.             lenmot = 0;
  237.             while(*s && !isspc(*s)) {++s;++lenmot;}
  238.             if(nbmot + nbcar + lenmot>=md) break;
  239.             ++nbmot; nbcar += lenmot;
  240.             }
  241.         if(*s && nbmot)
  242.             {
  243.             int nbreste = 0,divi = nbmot - 1;
  244.             s = debut_ligne;
  245.             do_spc(mg);
  246.             while(nbmot)
  247.                 {
  248.                 while(isspc(*s)) ++s;
  249.                 while(*s && !isspc(*s))
  250.                     {
  251.                     fputc(*s,stderr);
  252.                     ++s;
  253.                     }
  254.                 if(--nbmot)
  255.                     {
  256.                     int i = md - nbcar + nbreste;
  257.                     do_spc(i/divi);
  258.                     nbreste = i % divi;
  259.                     }
  260.                 }
  261.             fputc('\n',stderr);
  262.             }
  263.         else if(nbmot)
  264.             {
  265.             s = debut_ligne;
  266.             do_spc(mg);
  267.             while(nbmot)
  268.                 {
  269.                 while(isspc(*s)) ++s;
  270.                 while(*s && !isspc(*s))
  271.                     {
  272.                     fputc(*s,stderr);
  273.                     ++s;
  274.                     }
  275.                 if(--nbmot) fputc(' ',stderr);
  276.                 }
  277.             fputc('\n',stderr);
  278.             }
  279.         s = fin_ligne;
  280.         }
  281. end:    free(line); line = NULL;
  282.     }
  283.  
  284. static mchunk *addchunk(),*addsyschunk();
  285.  
  286. static char *procname()
  287.     {
  288.     static char ch[20];
  289.     char *s,*t;int l;
  290.     if(AP_procname) return AP_procname;
  291.     ifn(stack) return TRD("PILE AP_procname VIDE !",
  292.                   "EMPTY AP_procname STACK !");
  293.     for(s=ch,t=stack->name,l=0;*t && l<19;) {*s=*t;++s;++t;++l;}
  294.     if(l<19) *s++='*';
  295.     *s='\0';
  296.     return ch;
  297.     }
  298.  
  299. static int pile_vide()
  300.     {
  301.     if(cnt || stack) return 1;
  302.     return 0;
  303.     }
  304.  
  305. static void addsegchunk(sl,name)
  306.     ULONG sl;char *name;
  307.     {
  308.     ULONG haut,bas;
  309.  
  310.     sl <<= 2;
  311.     while(sl)
  312.         {
  313.         bas = sl-4; haut = bas + ((ULONG*)sl)[-1] - 1;
  314.         ifn(addsyschunk(bas, haut, name))
  315.             {
  316.             do_print(TRD(WARNING" Je ne peux allouer le block"
  317.                         " 0x%08x - 0x%08x (%s). Ce block"
  318.                         " ne sera pas pris en compte.",
  319.  
  320.                      WARNING" Can't alloc block 0x%08x -"
  321.                         " 0x%08x (%s). That block will"
  322.                         " be ignored."),
  323.                  bas, haut, name);
  324.             do_dump(0,LARG_LINE);
  325.             }
  326.         sl = (*(ULONG*)sl)<<2;
  327.         }
  328.     }
  329.  
  330. static void process_sys_chunk()
  331.     {
  332.     int tmp;
  333.     ULONG *sp;
  334.     mchunk *c;
  335. #ifdef    MANX
  336.     extern ULONG * _savesp;
  337.     sp = _savesp;
  338. #else
  339. #ifdef    _DCC
  340.     extern ULONG *_ExitSP;
  341.     sp = _ExitSP+11;
  342. #else
  343.     ULONG l[2];
  344.     l[1] = 1;
  345.     sp   = l;
  346. #endif
  347. #endif
  348.  
  349.     ifn(c = addsyschunk(0,1023,TRD("Vecteurs de base 680x0",
  350.                        "Basic 680x0 vectors")))
  351.         {
  352.         do_print(TRD(
  353.              WARNING" Je ne peux allouer le block representant"
  354.                 " les vecteurs de base. Ce block ne sera pas"
  355.                 " pris en compte.",
  356.  
  357.              WARNING" Can't alloc block for basic vectors. That"
  358.                 " block will be ignored."));
  359.         do_dump(0,LARG_LINE);
  360.         }
  361.     else c->attr &= ~attr_wr; /* lecture seulement...           */
  362.                   /* quoique ecriture peut-etre (qui va    */
  363.                   /* faire une indirection en ecriture       */
  364.                   /* dessus ?) */
  365.  
  366.     ifn(addsyschunk(ThisTask->BasPileTache,
  367.             ThisTask->HautPileTache - 1,
  368.             TRD("pile standard de la tache",
  369.                 "standard stack frame of task")))
  370.         {
  371.         do_print(TRD(
  372.              WARNING" Je ne peux allouer le block representant"
  373.                 " la pile de la tache. Ce block ne sera pas"
  374.                 " pris en compte: 0x%08x-0x%08x",
  375.  
  376.              WARNING" Can't alloc block for standard stack frame"
  377.                 " of task. That block will be ignored:"
  378.                 " 0x%08x-0x%08x"),
  379.  
  380.              ThisTask->BasPileTache,
  381.              ThisTask->HautPileTache - 1);
  382.         do_dump(0,LARG_LINE);
  383.         }
  384.  
  385.     if(((ULONG)&tmp < ThisTask->BasPileTache) ||
  386.        ((ULONG)&tmp > ThisTask->HautPileTache))
  387.         {
  388.         ULONG *haut = (ULONG*)((ULONG)sp + 8 - 1),
  389.               *bas  = (ULONG*)((ULONG)sp - sp[1] + 8);
  390.         ifn(addsyschunk(bas,haut,TRD(
  391.                 "pile supplementaire (CLI?) de la tache",
  392.                 "extra stack (CLI?) of task")))
  393.             {
  394.             do_print(TRD(
  395.                  WARNING" Je ne peux allouer le block"
  396.                     " representant la pile de la tache."
  397.                     " Ce block ne sera pas pris en"
  398.                     " compte: 0x%08x-0x%08x",
  399.  
  400.                  WARNING" Can't alloc block for stack of"
  401.                     " task. That block will be ignored:"
  402.                     " 0x%08x-0x%08x"),
  403.                  bas, haut);
  404.             do_dump(0,LARG_LINE);
  405.             }
  406.         }
  407.  
  408.     addsegchunk(((ULONG*)(ThisTask->SegList<<2))[3],TRD(
  409.             "segment du processus",
  410.             "segment process"));
  411.  
  412.     if(ThisTask->CLI)
  413.         { /* from CLI */
  414.         addsegchunk(((simplecli *)(ThisTask->CLI<<2))->Module,TRD(
  415.                 "segment du Module CLI",
  416.                 "segment Module CLI"));
  417.         }
  418.     }
  419.  
  420. static Warn()
  421.     {
  422.     fprintf(stderr,TRD(WARNING" Librairie non ouverte (%s)\n",
  423.                WARNING" Library not opened (%s)\n"), procname());
  424.     fprintf(stderr,TRD("Il faut ouvrir et fermer la librairie dans "
  425.                "main(). Par exemple:\n",
  426.  
  427.                "You should open the library in main(). For "
  428.                "example:\n"));
  429.     fprintf(stderr,"main(ac,av)\n");
  430.     fprintf(stderr,"    int ac; char *av[];\n");
  431.     fprintf(stderr,"    {\n");
  432.     fprintf(stderr,"    AP_Init();    /* "TRD("Ouverture librairie",
  433.                           "Opening library")" */\n");
  434.     fprintf(stderr,"    ...           /* "TRD("Code normal",
  435.                           "Your code")" */\n");
  436.     fprintf(stderr,"    AP_Close();   /* "TRD("Fermeture librairie",
  437.                           "Closing library")" */\n");
  438.     fprintf(stderr,"    }\n");
  439.     fprintf(stderr,TRD("L'execution continue sans APurify.\n",
  440.                "Execution goes on without APurify.\n"));
  441.     APflg |= APwarn;
  442.     }
  443.  
  444. void AP_Init()
  445.     {
  446.     register ULONG *tmp;
  447.     int var_sur_pile;
  448.  
  449.     APflg        = APopen|APlock|APreport;
  450.  
  451.     ThisTask    = FindTask(NULL);
  452.     mfirst        = NULL;
  453.  
  454.     Disable();
  455.     tmp        = (ULONG*)(((UBYTE*)StdAlloc)+14);
  456.     MallocProc  = SetFunction(*(ULONG*)4, LVOAllocMem, AsmAllocMem);
  457.     *tmp        = MallocProc;
  458.     tmp        = (ULONG*)(((UBYTE*)StdFree)+16);
  459.     FreeProc    = SetFunction(*(ULONG*)4, LVOFreeMem, AsmFreeMem);
  460.     *tmp        = FreeProc;
  461.     Enable();
  462.  
  463.     process_sys_chunk();
  464.  
  465.     APflg       &= ~APlock;
  466.     }
  467.  
  468. void AP_Close()
  469.     {
  470.     mchunk *c,*mc;
  471.  
  472.     APflg |= APlock;
  473.     ifn(APflg & APopen)
  474.         {
  475.         ifn(APflg & APwarn) Warn();
  476.         APflg &= ~APlock;
  477.         return;
  478.         }
  479.  
  480.     for(c=mfirst;c && (c->attr & attr_sys); c=c->next);
  481.     if(c)
  482.         {
  483.         do_print(TRD(
  484.              WARNING" Fermeture de la librairie sans"
  485.                 " desallocation du(des) block(s)"
  486.                 " suivant(s):",
  487.  
  488.              WARNING" Closing library without deallocation of"
  489.                 " the following block(s):"));
  490.         do_dump(0,LARG_LINE);
  491.         while(c)
  492.             {
  493.             do_print("- %s",blocks(c));
  494.             do_dump(MARG_LINE,LARG_LINE);
  495.             for(c=c->next;c && (c->attr & attr_sys); c=c->next);
  496.             }
  497.         }
  498.     for(c=mfirst;c;c=mc) {mc=c->next;free(c);}
  499.     mfirst = NULL;
  500.  
  501. /* warning inutile est stupide: la pile est independante de APURIFY.
  502.  * il est impossible que ca devienne vide qd on appelle AP_close(),
  503.  * par construction.
  504.     ifn(pile_vide())
  505.         {
  506.         do_print(TRD(
  507.              WARNING" Fermeture de la librairie sans etre"
  508.                 " retourne de la (des) procedure(s)"
  509.                 " suivante:",
  510.  
  511.              WARNING" Closing library without returning from the"
  512.                 " following procedure(s):"));
  513.         do_dump(0,LARG_LINE);
  514.         do
  515.             {
  516.             AP_unprotect();
  517.             do_print("- %s",procname());
  518.             do_dump(MARG_LINE,LARG_LINE);
  519.             }
  520.         while(!pile_vide());
  521.         }
  522. */
  523.     Disable();
  524.     SetFunction(*(ULONG*)4, LVOAllocMem, MallocProc);
  525.     SetFunction(*(ULONG*)4, LVOFreeMem, FreeProc);
  526.     Enable();
  527.     APflg &= ~(APlock|APopen);
  528.     }
  529.  
  530. void AP_Report(flag)
  531.     int flag;
  532.     {
  533.     if(flag) APflg |=  APreport;
  534.     else     APflg &= ~APreport;
  535.     }
  536.  
  537. static int chunkcmp(c1, c2)
  538.     mchunk *c1,*c2;
  539.     {
  540.     ULONG c1d,c1f,c2d,c2f;
  541.     if((c1d = c1->deb) < (c2d = c2->deb))
  542.         {
  543.         if((c1f = c1->fin) <  c2d) return -2;
  544.         if(c1f <= c2->fin) return -1;
  545.         return 3;
  546.         }
  547.     if(c1d > (c2f = c2->fin))  return 2;
  548.     if((c1f = c1->fin) <= c2f) return 0;
  549.     if(c1f > c2f) return 1;
  550.     }
  551.  
  552. /*
  553.  * dump complet des chunks... permet de voir si les listes sont bien
  554.  * ordonnees
  555.  */
  556. /*
  557. static dc()
  558.     {
  559.     mchunk *c = mfirst;
  560.     printf("dc(): ");
  561.     while(c)
  562.         {
  563.         printf("%s",blocks(c));
  564.         if(c = c->next) printf(" %d ",chunkcmp(c->prev,c));
  565.         }
  566.     printf("\n");
  567.     }
  568. /**/
  569.  
  570. static struct cache {long hit;mchunk *c;} cache[CACHE_SIZE];
  571.  
  572. static mchunk *cachehit(ck)
  573.     mchunk *ck;
  574.     { /* lecture cache */
  575.     struct cache *cc=cache;
  576.     int i;
  577.  
  578.     for(i = CACHE_SIZE + 1;--i && (cc->c);++cc) if(!chunkcmp(ck,cc->c))
  579.         {
  580.         ++(cc->hit);
  581.         return cc->c;
  582.         }
  583.     return NULL;
  584.     }
  585.  
  586. static void uncachehit(c)
  587.     mchunk *c;
  588.     { /* ecriture cache */
  589.     struct cache *cc,*cv; int i;
  590.  
  591.     cv = cache;
  592.     if(cv->c) for(cc = cv+1, i = CACHE_SIZE;--i;++cc)
  593.         {
  594.         ifn(cc->c) {cv = cc;break;}
  595.         if(cc->hit < cv->hit) cv = cc;
  596.         }
  597.     cv->c    = c;
  598.     cv->hit = 0;
  599.     }
  600.  
  601. static void cacheflush(ck)
  602.     mchunk *ck;
  603.     {
  604.     int i; struct cache *cc;
  605.  
  606.     for(cc = cache, i = CACHE_SIZE+1; --i; ++cc) ifn(cc->c - ck)
  607.         {
  608.         for(;--i;++cc) cc[0]=cc[1];
  609.         cc->c    = NULL;
  610.         cc->hit = 0;
  611.         return;
  612.         }
  613.     }
  614.  
  615. static mchunk *findchunk(ck)
  616.     mchunk *ck;
  617.     {
  618.     mchunk *c = mfirst, *pc;
  619.     int lastcmp;
  620.  
  621.     ifn(c) return NULL;
  622.  
  623.     if(pc = cachehit(ck)) return pc;
  624.  
  625.     if((lastcmp = chunkcmp(ck, c)) - 2) goto suite;
  626.  
  627.     while((pc = c->next) && !((lastcmp = chunkcmp(ck, pc)) - 2)) c = pc;
  628.  
  629.     if(pc) c = pc;
  630. suite:
  631.     ifn(lastcmp) uncachehit(c);
  632.     return c;
  633.     }
  634.  
  635. static int i_addchunk(c)
  636.     mchunk *c;
  637.     {
  638.     mchunk *d;
  639.  
  640.     ifn(d = findchunk(c)) {mfirst = c; return 1;}
  641.     switch(chunkcmp(c,d))
  642.         {
  643.         case -2:
  644.         c->next = d;
  645.         if(c->prev = d->prev) c->prev->next = c; else mfirst = c;
  646.         d->prev = c;
  647.         break;
  648.  
  649.         case 2:
  650.         c->prev = d;
  651.         if(c->next = d->next) {c->next->prev = c;}
  652.         d->next = c;
  653.         break;
  654.  
  655.         case -1:
  656.         case 0:
  657.         case 1:
  658.         case 3:
  659.         do_print(TRD(ERROR" Le block nouvellement alloue %s",
  660.                  ERROR" Newly allocated block %s"), blocks(c));
  661.         do_print(TRD(" recouvre le block deja alloue %s",
  662.                  " overlaps the already allocated block %s"),
  663.              blocks(d));
  664.         do_dump(0,LARG_LINE);
  665.         return 0;
  666.         break;
  667.         }
  668.     return 1;
  669.     }
  670.  
  671. static mchunk *addsyschunk(cd,cf,name)
  672.     ULONG cd,cf;
  673.     char *name;
  674.     {
  675.     mchunk *c;
  676.  
  677.     ifn(c = malloc(sizeof(*c))) return 0;
  678.     c->next = c->prev = NULL;
  679.     c->deb    = cd;
  680.     c->fin    = cf;
  681.     c->name = name;
  682.     c->attr = attr_rd|attr_wr|attr_sys;
  683.     ifn(i_addchunk(c)) {free(c);return NULL;} else return c;
  684.     }
  685.  
  686. static mchunk *addchunk(cd,cf)
  687.     ULONG cd,cf;
  688.     {
  689.     mchunk *c;
  690.  
  691.     ifn(c = malloc(sizeof(*c))) return 0;
  692.     c->next = c->prev = NULL;
  693.     c->deb    = cd;
  694.     c->fin    = cf;
  695.     c->name = procname();
  696.     c->attr = attr_rd|attr_wr;
  697.     ifn(i_addchunk(c)) {free(c);return NULL;} else return c;
  698.     }
  699.  
  700. static int subchunk(cd,cf)
  701.     ULONG cd,cf;
  702.     {
  703.     mchunk *c;
  704.     ifn(c = mfirst)
  705.         {
  706.         do_print(TRD(ERROR" Liberation de memoire dans %s alors"
  707.                   " qu'aucun block memoire n'est alloue",
  708.  
  709.                  ERROR" Freeing memory in %s while no memory"
  710.                   " block is allocated"),
  711.              procname());
  712.         do_dump(0,LARG_LINE);
  713.         return 0;
  714.         }
  715.     while(c && (cd > c->deb)) c = c->next;
  716.     if(c && (c->deb == cd && c->fin == cf))
  717.         {
  718.         cacheflush(c);
  719.         if(c->next)
  720.             {
  721.             c->next->prev = c->prev;
  722.             if(c->prev) c->prev->next = c->next;
  723.             else        mfirst = c->next;
  724.             free(c);
  725.             }
  726.         else
  727.             {
  728.             if(c->prev) c->prev->next = NULL;
  729.             else        mfirst = NULL;
  730.             free(c);
  731.             }
  732.         return 1;
  733.         }
  734.     do_print(TRD(ERROR" Aucun block memoire alloue ne correspond a"
  735.               " 0x%08x - 0x%08x (%s)",
  736.  
  737.              ERROR" No memory block matches 0x%08x - 0x%08x (%s)"),
  738.          cd, cf, procname());
  739.     do_dump(0,LARG_LINE);
  740.     return 0;
  741.     }
  742.  
  743. static void entre(type,c,c1,c2) /* acces entre 2 blocks */
  744.     char *type;
  745.     mchunk *c,*c1,*c2;
  746.     {
  747.     do_print(TRD(ERROR" Block %s\n",
  748.              ERROR" Block %s\n"),blocks(c));do_dump(0,LARG_LINE);
  749.  
  750.     do_print(TRD("%s illegale ",
  751.              "Illegal %s "), type);
  752.  
  753.     ifn(c1)      do_print(TRD("avant le block %s (depassement de %d"
  754.                   " octet(s))",
  755.  
  756.                   "before block %s (overstepping of %d"
  757.                   " byte(s))"),
  758.                   blocks(c2), c2->deb - c->deb);
  759.  
  760.     else ifn(c2) do_print(TRD("apres le block %s (depassement de %d"
  761.                   " octet(s))",
  762.  
  763.                   "after block %s (overstepping of %d"
  764.                   " byte(s))"),
  765.                   blocks(c1), c->fin - c1->fin);
  766.     else         {
  767.              do_print(TRD("entre les blocks ",
  768.                   "between blocks "));
  769.  
  770.              do_print(TRD("%s (depassement de %d octet(s)) et ",
  771.                   "%s (overstepping of %d byte(s)) and "),
  772.                   blocks(c1), c->deb - c1->fin);
  773.  
  774.              do_print(TRD("%s (depassement de %d octet(s))",
  775.                   "%s (overstepping of %d byte(s))"),
  776.                   blocks(c2),c->fin - c2->deb);
  777.              }
  778.     do_dump(MARG_LINE,LARG_LINE);
  779.     }
  780.  
  781. static void achev(type,c,c1)   /* a cheval sur un block */
  782.     char *type;
  783.     mchunk *c,*c1;
  784.     {
  785.     int d;
  786.     do_print(TRD(ERROR" Block %s",
  787.              ERROR" Block %s"), blocks(c));do_dump(0,LARG_LINE);
  788.     do_print(TRD("%s debordant le block %s ",
  789.              "Overstepping %s on block %s "), type, blocks(c1));
  790.     d = c1->deb - c->deb;
  791.     if(d<0) d = c1->fin - c->fin;
  792.     TRD(
  793.     {
  794.     if(d<0) do_print("a droite de %d octet(s)", -d);
  795.     else    do_print("a gauche de %d octet(s)",  d);
  796.     },
  797.     {
  798.     if(d<0) do_print("of %d byte(s) rightward", -d);
  799.     else    do_print("of %d byte(s) leftward",   d);
  800.     });
  801.     do_dump(MARG_LINE,LARG_LINE);
  802.     }
  803.  
  804. void AP_rd(pt,len)
  805.     ULONG pt,len;
  806.     {
  807.     mchunk mc,*c;
  808.     ifn(APflg & APopen) {ifn(APflg & APwarn) Warn();return;}
  809.     APflg |= APlock;
  810. /*    printf("Read : %08x-%08x par %s\n",pt,pt+len-1,procname());   /**/
  811.     mc.deb    = pt;
  812.     mc.fin    = pt + len - 1;
  813.     mc.name = procname();
  814.     mc.attr = attr_rd;
  815.     ifn(c = findchunk(&mc))
  816.         {
  817.         do_print(TRD(ERROR" Aucun block memoire alloue (%s) !",
  818.                  ERROR" No memory block allocated (%s) !"),
  819.              procname());
  820.         do_dump(0,LARG_LINE);
  821.         }
  822.     else
  823.         {
  824.         switch(chunkcmp(&mc,c))
  825.             {
  826.             case -2:
  827.             entre(TRD("Lecture","reading"), &mc, c->prev, c);
  828.             break;
  829.  
  830.             case 2:
  831.             entre(TRD("Lecture","reading"), &mc, c, c->next);
  832.             break;
  833.  
  834.             case -1:
  835.             achev(TRD("Lecture","reading"), &mc, c);
  836.             break;
  837.  
  838.             case 1:
  839.             achev(TRD("Lecture","reading"), &mc, c);
  840.             break;
  841.  
  842.             case 3:
  843.             TRD(
  844.             {
  845.             do_print(ERROR" Bizzare, erreur impossible: le block"
  846.                       " %s ",blocks(&mc));
  847.             do_print("recouvre le block %s",blocks(c));
  848.             },{
  849.             do_print(ERROR" Strange, impossible error: block %s",
  850.                  blocks(&mc));
  851.             do_print("is overlapping block %s", blocks(c));
  852.             })
  853.             do_dump(0,LARG_LINE);
  854.             break;
  855.  
  856.             case 0:
  857.             ifn((mc.attr & c->attr) == mc.attr)
  858.                 {
  859.                 do_print(TRD(ERROR" Block %s",
  860.                          ERROR" Block %s"),
  861.                      blocks(&mc));do_dump(0,LARG_LINE);
  862.                 do_print(TRD("Erreur de protection en"
  863.                          " lecture sur le block %s\n",
  864.  
  865.                          "Protection error in reading"
  866.                          " block %s\n"), blocks(c));
  867.                 do_dump(MARG_LINE,LARG_LINE);
  868.                 }
  869.             break;
  870.             }
  871.         }
  872.     APflg &= ~APlock;
  873.     }
  874.  
  875. void AP_wr(pt,len)
  876.     ULONG pt,len;
  877.     {
  878.     mchunk mc,*c;
  879.     ifn(APflg & APopen) {ifn(APflg & APwarn) Warn();return;}
  880.     APflg |= APlock;
  881. /*    printf("Write: %08x-%08x par %s\n",pt,pt+len-1,procname());   /**/
  882.     mc.deb    = pt;
  883.     mc.fin    = pt + len - 1;
  884.     mc.name = procname();
  885.     mc.attr = attr_wr;
  886.     ifn(c = findchunk(&mc))
  887.         {
  888.         do_print(TRD(ERROR" Aucun block memoire alloue (%s)",
  889.                  ERROR" No memory block allocated (%s)"),
  890.              procname());
  891.         do_dump(0,LARG_LINE);
  892.         }
  893.     else
  894.         {
  895.         switch(chunkcmp(&mc,c))
  896.             {
  897.             case -2:
  898.             entre(TRD("Ecriture","writing"), &mc, c->prev, c);
  899.             break;
  900.  
  901.             case 2:
  902.             entre(TRD("Ecriture","writing"), &mc, c, c->next);
  903.             break;
  904.  
  905.             case -1:
  906.             achev(TRD("Ecriture","writing"), &mc, c);
  907.             break;
  908.  
  909.             case 1:
  910.             achev(TRD("Ecriture","writing"), &mc, c);
  911.             break;
  912.  
  913.             case 3:
  914.             do_print(TRD(ERROR" Bizzare, erreur impossible: le"
  915.                       " block %s ",
  916.  
  917.                      ERROR" Strange, impossible error: block"
  918.                       " %s "),
  919.                  blocks(&mc));
  920.             do_print(TRD("recouvre le block %s",
  921.                      "is overlapping block %s"),
  922.                  blocks(c));
  923.             do_dump(0,LARG_LINE);
  924.             break;
  925.  
  926.             case 0:
  927.             ifn((mc.attr & c->attr) == mc.attr)
  928.                 {
  929.                 do_print(TRD(ERROR" Block %s",
  930.                          ERROR" Block %s"),
  931.                      blocks(&mc));
  932.                 do_dump(0,LARG_LINE);
  933.                 do_print(TRD("Erreur de protection en"
  934.                          " ecriture sur le block %s",
  935.  
  936.                          "Protection error in writing on"
  937.                          " block %s"),
  938.                      blocks(c));
  939.                 do_dump(MARG_LINE,LARG_LINE);
  940.                 }
  941.             break;
  942.             }
  943.         }
  944.     APflg &= ~APlock;
  945.     }
  946.  
  947. void AP_protect()
  948.     {
  949.     pile *s;
  950.     APflg |= APlock;
  951.     ifn(s = malloc(sizeof(*s))) {++cnt;goto end;}
  952.     s->next = stack;
  953.     s->name = AP_procname;
  954.     AP_procname = NULL;
  955.     stack = s;
  956. end:    APflg &= ~APlock;
  957.     }
  958.  
  959. void AP_unprotect()
  960.     {
  961.     pile *s;
  962.     APflg |= APlock;
  963.     if(cnt) --cnt;
  964.     else
  965.         {
  966.         s = stack;stack = s->next;
  967.         AP_procname = s->name;
  968.         free(s);
  969.         }
  970.     APflg &= ~APlock;
  971.     }
  972.  
  973. ULONG PubAllocMem(len, type)
  974.     register ULONG len, type;
  975.     {
  976.     register ULONG p;
  977.  
  978.     geta4();
  979.  
  980.     if((FindTask(NULL) - ThisTask)) goto normal;
  981.     ifn(APflg & APopen)
  982.         {
  983.         ifn(APflg & APwarn) Warn();
  984.         goto normal;
  985.         }
  986.     if(APflg & APlock) goto normal;
  987.  
  988.     APflg |= APlock;
  989.  
  990. /*    fprintf(stderr, "Malloc(%d,%d) par %s\n", len, type, procname());/**/
  991.  
  992.     if(p = (ULONG)StdAlloc(len, type))
  993.     ifn(addchunk(p, p + len - 1)) {StdFree(p, len);p = NULL;}
  994.  
  995. /*    dc(); /**/
  996.  
  997.     APflg &= ~APlock;
  998.     return p;
  999. normal:
  1000.     return (ULONG)StdAlloc(len, type);
  1001.     }
  1002.  
  1003. void PubFreeMem(ptr, len)
  1004.     register ULONG ptr, len;
  1005.     {
  1006.     geta4();
  1007.  
  1008.     if((FindTask(NULL) - ThisTask)) goto normal;
  1009.     ifn(APflg & APopen)
  1010.         {
  1011.         ifn(APflg & APwarn) Warn();
  1012.         goto normal;
  1013.         }
  1014.     if(APflg & APlock) goto normal;
  1015.  
  1016.     APflg |= APlock;
  1017.  
  1018. /*    fprintf(stderr, "Free(%08x,%d) par %s\n", ptr, len, procname()); /**/
  1019.  
  1020.     if(subchunk(ptr, ptr + len - 1)) StdFree(ptr, len);
  1021.  
  1022.     APflg &= ~APlock;
  1023.     return;
  1024. normal:
  1025.     StdFree(ptr, len);
  1026.     }
  1027.  
  1028.